/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.compomics.specificpeakfinder;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import uk.ac.ebi.jmzml.model.mzml.BinaryDataArray;
import uk.ac.ebi.jmzml.model.mzml.Spectrum;
import uk.ac.ebi.jmzml.xml.io.MzMLObjectIterator;
import uk.ac.ebi.jmzml.xml.io.MzMLUnmarshaller;

/**
 *
 * @author Jonas
 */
public class MzmlReader {

    private static final Logger LOGGER = Logger.getLogger(MzmlReader.class);

    public List iterateAllSpectra(File mzmlFile) {

        // Unmarshall the provided mzmlFile once
        MzMLUnmarshaller unmarshaller = new MzMLUnmarshaller(mzmlFile);
        // Index all the spectra in the mzmlFile in a List
        MzMLObjectIterator<Spectrum> spectrumIterator = unmarshaller.unmarshalCollectionFromXpath("/run/spectrumList/spectrum", Spectrum.class);

        LOGGER.info("Scanning through mzML-file...");
        List<SpectrumVariables> spectrumVariables = new ArrayList<SpectrumVariables>();

        // Loop over all the spectra contained in the list
        while (spectrumIterator.hasNext()) {

            // Initiate spectrum with the next spectrum in the list
            Spectrum spectrum = spectrumIterator.next();
            // Get the scannumber
            int startOfScanNumber = spectrum.getId().lastIndexOf("scan");
            int scanNumber = Integer.parseInt(spectrum.getId().substring(startOfScanNumber + 5));   // Validated

            // Make a binaryDataArray list to hold all the spectra m/z and intensities
            List<BinaryDataArray> binaryDataArrayList = spectrum.getBinaryDataArrayList().getBinaryDataArray();
            BinaryDataArray mzBinaryDataArray = (BinaryDataArray) binaryDataArrayList.get(0);
            // Make one array to hold mzValues and another one to hold intensities
            Number[] mzNumbers = mzBinaryDataArray.getBinaryDataAsNumberArray();
            BinaryDataArray intBinaryDataArray = (BinaryDataArray) binaryDataArrayList.get(1);
            Number[] intNumbers = intBinaryDataArray.getBinaryDataAsNumberArray();
            
            SpectrumVariables currentSpectrum = new SpectrumVariables(scanNumber);
            
            // Check if the peaks at m/z 126.0913 or 143.1179 are present
            for (int i = 0; i < mzNumbers.length; i++){
                
                double firstMassError = Math.abs((mzNumbers[i].doubleValue()-126.0913)/126.0913);
//                double secondMassError = Math.abs((mzNumbers[i].doubleValue()-143.1179)/143.1179);
                
                if (firstMassError <= 0.000005){
                    currentSpectrum.setFirstIntensity(intNumbers[i].doubleValue());
                    currentSpectrum.setFirstFound(true);
                }
                
//                if (secondMassError <= 0.000005){
//                    currentSpectrum.setSecondIntensity(intNumbers[i].doubleValue());
//                    currentSpectrum.setSecondFound(true);
//                }
            }
            // If one of the two m/z values are found, check for the highest peak in the spectrum by looping through the intensities-array
            if ((currentSpectrum.getFirstIntensity() > 0.0)){
                double highestIntensity = 0.0;
                int highestIntensityPosition = 0;
                
                for (int i = 0; i < intNumbers.length; i++){
                    if (intNumbers[i].doubleValue() > highestIntensity){
                        highestIntensity = intNumbers[i].doubleValue();
                        highestIntensityPosition = i;
                    }
                }
                currentSpectrum.setHighestPeak(highestIntensity);
                
                // Calculate the relative intensity of both m/z values compared to the found highest peak intensity
                if (currentSpectrum.getFirstIntensity() > 0.0){
                currentSpectrum.setFirstRelativeIntensity((currentSpectrum.getFirstIntensity()/highestIntensity)*100);                    
                }
//                if (currentSpectrum.getSecondIntensity() > 0.0){
//                currentSpectrum.setSecondRelativeIntensity((currentSpectrum.getSecondIntensity()/highestIntensity)*100);                    
//                }
                spectrumVariables.add(currentSpectrum);
            }
        }
        LOGGER.info("Scanning mzML-file finished!");
        
        return spectrumVariables;
    }   
}
